package com.boruan.shengtangfeng.core.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.boruan.shengtangfeng.core.dao.*;
import com.boruan.shengtangfeng.core.entity.*;
import com.boruan.shengtangfeng.core.utils.GlobalReponse;
import com.boruan.shengtangfeng.core.vo.MessageNumVo;
import org.beetl.sql.core.db.KeyHolder;
import org.beetl.sql.core.engine.PageQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.boruan.shengtangfeng.core.dto.NoticeSearch;
import com.boruan.shengtangfeng.core.service.INoticeService;
import com.boruan.shengtangfeng.core.vo.NoticeVo;

/**
 * 
 * @author liuguangqiang
 * @date 2016年8月10日 上午9:36:16
 */
@Service
@Transactional(readOnly = true)
public class NoticeService implements INoticeService {
	private static Logger logger = LoggerFactory.getLogger(NoticeService.class);
	@Autowired
	private INoticeDao noticeDao;
	@Autowired
	private INoticeUserDao noticeUserDao;
	@Autowired
	private IApplyForDao applyForDao;
	@Autowired
	private IKickOutDao kickOutDao;
	@Autowired
	private IClassAndDao classAndDao;
	@Autowired
	private IJobBackDao jobBackDao;
	@Autowired
	private IVideoFriendDao videoFriendDao;
	@Autowired
	private IInviteAddGroupDao inviteAddGroupDao;
	@Autowired
	private IApplyForDeletedDao applyForDeletedDao;
	@Autowired
	private IJobBackDeletedDao jobBackDeletedDao;
	@Autowired
	private IUserDao userDao;
	@Autowired
	private IGroupMembersDao groupMembersDao;

	@Override
	public void pageQueryVo(PageQuery<NoticeVo> pageQuery,NoticeSearch noticeSearch) {
		pageQuery.setParas(noticeSearch);
		noticeDao.pageQueryVo(pageQuery);
	}
	
	@Override
	public void pageQuery(PageQuery<Notice> pageQuery,NoticeSearch noticeSearch) {
	    pageQuery.setParas(noticeSearch);
	    noticeDao.pageQuery(pageQuery);
	}
	
	@Override
	@Transactional(readOnly = false)
	public void save(Notice notice) {
		if (notice.getId()==null) {
			KeyHolder kh=noticeDao.insertReturnKey(notice);
			notice.setId(kh.getLong());
		}else{
		    noticeDao.updateById(notice);
		}
	}
	@Override
	@Transactional
	public Notice addNotice(Integer category, Integer type, Long objectId, Long userId, String title,String content) {
	    //通知要做成一对多
	    Notice notice=new Notice();
	    notice.setCategory(category);
	    notice.setCreateBy(userId.toString());
	    notice.setCreateTime(new Date());
	    notice.setIsDeleted(false);
	    notice.setObjectId(objectId);
	    notice.setTitle(title);
	    notice.setContent(content);
	    notice.setType(type);
	    KeyHolder noticeKey=noticeDao.insertReturnKey(notice);
	    notice.setId(noticeKey.getLong());
	    //平台通知需要发送给所有用户
	    if(category==1) {
	        noticeUserDao.insertAllUser(noticeKey.getLong());
	    }else {
	        NoticeUser noticeUser=new NoticeUser();
	        noticeUser.setNoticeId(noticeKey.getLong());
	        noticeUser.setUserId(userId);
	        noticeUser.setIsDeleted(false);
	        noticeUser.setReaded(false);
	        noticeUserDao.insert(noticeUser);
	    }
	    return notice;
	}

	/**
	 * 删除通知
	 *
	 * @param id
	 * @param userId
	 * @return
	 */
	@Override
	@Transactional(readOnly = false)
	public GlobalReponse deletedNotice(Long id, Long userId) {
		noticeUserDao.deletedNotice(id,userId);
		return GlobalReponse.success("删除成功");
	}

	@Override
    public GlobalReponse<MessageNumVo> getCount(NoticeSearch noticeSearch) {
		MessageNumVo numVo = new MessageNumVo();
		Long userId = noticeSearch.getUserId();
		User user = userDao.unique(userId);
		long tongNum = noticeDao.getCount(noticeSearch);
		//新好友未读消息数量
		Long newFriendNum = applyForDao.getNewFriendNum(userId);
		numVo.setFriendNum(newFriendNum);

		//加群消息
		Long groupNum = 0L;
		ApplyFor applyFor = new ApplyFor();
		applyFor.setApplyId(userId);
		applyFor.setType(1);
		List<ApplyFor> zFors = applyForDao.getNewGroup(applyFor);
		if (!zFors.isEmpty()) {
			for (ApplyFor zFor : zFors) {
				ApplyForDeleted single = applyForDeletedDao.createLambdaQuery().andEq(ApplyForDeleted::getApplyTableId, zFor.getId()).andEq(ApplyForDeleted::getUserId, userId).andEq(ApplyForDeleted::getIsDeleted, false).single();
				if (single == null) {
					groupNum += 1;
				}
			}
		}
		if (user.getUserType().equals(2)){
			applyFor.setApplyId(null);
			List<ApplyFor> bFors = applyForDao.getNewGroup(applyFor);
			List<Long> rIds = bFors.stream().map(ApplyFor::getRelevanceId).distinct().collect(Collectors.toList());
			List<Integer> list = Arrays.asList(1,2);
			for (ApplyFor bFor : bFors) {
				for (Long rId : rIds) {
					GroupMembers single = groupMembersDao.createLambdaQuery().andEq(GroupMembers::getUserId, userId).andEq(GroupMembers::getGroupChatId, rId).andIn(GroupMembers::getType, list).andEq(GroupMembers::getIsDeleted, false).single();
					if (single != null && bFor.getRelevanceId().equals(single.getGroupChatId())) {
						ApplyForDeleted applyForDeleted = applyForDeletedDao.createLambdaQuery().andEq(ApplyForDeleted::getApplyTableId, bFor.getId()).andEq(ApplyForDeleted::getUserId, userId).andEq(ApplyForDeleted::getIsDeleted, false).single();
						if (applyForDeleted == null) {
							groupNum += 1;
						}
					}
				}
			}
		}

		long kickCount = kickOutDao.createLambdaQuery().andEq(KickOut::getUserId, userId).andEq(KickOut::getType, 1).andEq(KickOut::getIsRead, 0).andEq(KickOut::getIsDeleted, false).count();
		groupNum += kickCount;
		long inviteCount = inviteAddGroupDao.createLambdaQuery().andEq(InviteAddGroup::getInviteeId, userId).andEq(InviteAddGroup::getIsRead, 0).andEq(InviteAddGroup::getIsDeleted, false).count();
		groupNum += inviteCount;
		numVo.setGroupNum(groupNum);

		//班级消息
		Long classNum = 0L;
		ApplyFor applyFor1 = new ApplyFor();
		applyFor1.setApplyId(userId);
		applyFor1.setType(2);
		List<ApplyFor> zFors1 = applyForDao.getNewClass(applyFor1);
		if (!zFors.isEmpty()) {
			for (ApplyFor zFor : zFors1) {
				ApplyForDeleted single = applyForDeletedDao.createLambdaQuery().andEq(ApplyForDeleted::getApplyTableId, zFor.getId()).andEq(ApplyForDeleted::getUserId, userId).andEq(ApplyForDeleted::getIsDeleted, false).single();
				if (single == null) {
					classNum += 1;
				}
			}
		}
		if (user.getUserType().equals(2)){
			//其他人申请加入我创建的班级
			List<ClassAnd> ands = classAndDao.createLambdaQuery().andEq(ClassAnd::getCreateBy, userId).andEq(ClassAnd::getIsDeleted, false).select();
			if (ands.size() > 0) {
				for (ClassAnd and : ands) {
					applyFor1.setApplyId(null);
					applyFor1.setRelevanceId(and.getId());
					List<ApplyFor> bFors1 = applyForDao.getNewClass(applyFor1);
					for (ApplyFor bFor : bFors1) {
						ApplyForDeleted apply = applyForDeletedDao.createLambdaQuery().andEq(ApplyForDeleted::getApplyTableId, bFor.getId()).andEq(ApplyForDeleted::getUserId, userId).andEq(ApplyForDeleted::getIsDeleted, false).single();
						if (apply == null) {
							classNum += 1;
						}
					}
				}
			}
		}
		long kickCount1 = kickOutDao.createLambdaQuery().andEq(KickOut::getUserId, userId).andEq(KickOut::getType, 1).andEq(KickOut::getIsRead, 0).andEq(KickOut::getIsDeleted, false).count();
		classNum+=kickCount1;


		JobBack jobBack = new JobBack();
		if (user.getUserType().equals(2)){
			jobBack.setCreateBy(userId.toString());
			jobBack.setStatus(1);
		}else {
			jobBack.setUserId(userId);
			jobBack.setStatus(0);
		}
		List<JobBack> jobBacks = jobBackDao.getStudentJobBack(jobBack);
		for (JobBack back : jobBacks) {
			JobBackDeleted single = jobBackDeletedDao.createLambdaQuery().andEq(JobBackDeleted::getJobBackId, back.getId()).andEq(JobBackDeleted::getUserId, userId).andEq(JobBackDeleted::getIsDeleted, false).single();
			if (single == null) {
				classNum+=1;
			}else {
				if (single.getIsRead()==0){
					classNum+=1;
				}
			}
		}
		numVo.setClassNum(classNum);

		//互动消息
		long videoCount = videoFriendDao.createLambdaQuery().andEq(VideoFriend::getFriendId, userId).andEq(VideoFriend::getIsRead, 0).andEq(VideoFriend::getIsDeleted, false).count();
		numVo.setInteractiveNum(videoCount);
		numVo.setZongNum(tongNum+newFriendNum+groupNum+classNum);
		return GlobalReponse.success(numVo);
	}

    @Override
    public Notice findById(Long id) {
        return noticeDao.single(id);
    }

    @Override
    @Transactional
    public void setRead(Long noticeId, Long userId) {
        noticeUserDao.setRead(noticeId,userId);
    }
    
	
}
